////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include "MessageDispatcher.hpp"
#include "../Entity/BaseObject.hpp"
#include "../Entity/EntityManager.hpp"

#include <SmegTools/Debug/DebugNew.hpp>

namespace smeg {
    namespace core {
        
////////////////////////////////////////////////////////////
/// Default Constructor
////////////////////////////////////////////////////////////
MessageDispatcher::MessageDispatcher()
{
}
    
////////////////////////////////////////////////////////////
/// Destructor
////////////////////////////////////////////////////////////
MessageDispatcher::~MessageDispatcher()
{
}

////////////////////////////////////////////////////////////
/// Change the state of the entity
////////////////////////////////////////////////////////////
void MessageDispatcher::DispatchMessage(    float _fDelay,
                                            BaseObject* _pSender,
                                            BaseObject* _pReceiver,
                                            int _iMessageType,
                                            void* _pExtraInfo ) {
    if ( _pSender && _pReceiver ) {
        MessageInfo newMsg( _fDelay,
                            (int)_pSender,
                            (int)_pReceiver,
                            _iMessageType,
                            _pExtraInfo );

        if ( _fDelay <= 0.0f ) {
            Discharge( _pReceiver, newMsg );
        } else {
            newMsg.m_fDelay = m_Clock.getElapsedTime().asSeconds() + _fDelay;

            m_MessageQueue.insert( newMsg );
        }
    }
}

////////////////////////////////////////////////////////////
/// Update the message dispatcher, send message info that need sending
////////////////////////////////////////////////////////////
void MessageDispatcher::Update() {
    float fCurrentTime = m_Clock.getElapsedTime().asSeconds();

    while ( !m_MessageQueue.empty() &&
        m_MessageQueue.begin()->m_fDelay < fCurrentTime ) {
        Discharge( reinterpret_cast<BaseObject*>(m_MessageQueue.begin()->m_iReceiverID), *m_MessageQueue.begin() );

        m_MessageQueue.erase( m_MessageQueue.begin() );
    }
}

////////////////////////////////////////////////////////////
/// Discharge a message to its receiver
////////////////////////////////////////////////////////////
void MessageDispatcher::Discharge( BaseObject* _pReceiver, const MessageInfo& _msg ) {
    _pReceiver->HandleMessage( _msg );
}

    } // namespace core
} // namespace smeg